﻿#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import re
import hashlib as md5
import time
import xml.etree.cElementTree as xmllib
import xml.dom.minidom as minidom
import xlrd

#
from __init__ import *

pglobal = re.compile(r'^0[^_]+[_](\w+)[.]xls\w*')
pother = re.compile(r'^([^_]+)[_]([^_]+)[_]([^.]+)[.]xls\w*')


#import generator
import datatypefile_generator as gen
generator = gen.DataTypeFileGenerator("Dist3Demo", nslist=nslist)

def Init():
    generator.xdict={}
    for k in nslist:
        nslist[k][2] = None

cs = sys.getdefaultencoding()
dcs = "utf-8"
if cs == "ascii":
    dcs = "gbk"

#Generate UUID
def GenerateUUIDByName(name, ns=None):
    if ns != None:
        name = ns + "." + name
    s = md5.md5(md5.md5(name).hexdigest()).hexdigest()
    return "-".join( (s[:8],s[8:12], s[12:16], s[16:20],s[20:]) ).upper()
def GenerateGUIDByName(name, ns=None):
    uuid = GenerateUUIDByName(name, ns)
    return "{"+uuid + "}"

class BaseContext(dict):
    #Customizing attribute access 'obj.name'
    def __getattr__(self, name):
        name = name.lower()
        if self.has_key(name):
            return self[name]
        else:
            raise AttributeError("The [%s] is not a valid attribute" % name)
    def __setattr__(self, name, value):
        name = name.lower()
        self.__setitem__(name, value)
    def __missing__(self, key):
        lkey = key.lower()
        if self.has_key(lkey):
            return self[lkey]
        else:
            #print "Missing key[%s]." % key
            return ""

class DSCFileGenerator:
    def __init__(self, name, ctx, **kw):
        if type(kw) == dict:
            self.__dict__ = kw
        self.name = name
        self.ctx = ctx
    #Customizing attribute access 'obj.name'
    def __getattr__(self, name):
        name = name.lower()
        if self.__dict__.has_key(name):
            return self.__dict__[name]
        else:
            return ""
            #raise AttributeError("The [%s] is not a valid attribute" % name)
    def __setattr__(self, name, value):
        name = name.lower()
        self.__dict__[name] = value
    def __delattr__(self, name):
        if self.__dict__.has_key(name):
            self.__dict__.pop(name)
    #Generator DSC file
    def Generate(self):
        self.root = xmllib.Element("Component:Component_Define", {"xmlns:Types":"http://www.appsoft.com.cn/Core/Types",
                                                         "xsi:schemaLocation":"http://www.appsoft.com.cn/Component ../Component.xsd",
                                                         "xmlns:Component":"http://www.appsoft.com.cn/Component",
                                                         "xmlns:xlink":"http://www.w3.org/1999/xlink",
                                                         "xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance"})
        comment = xmllib.Comment("Edited with Autotools by LMice TEAM, generated by ElementTree(Python)")
        self.root.append(comment)
        
        self.GenerateProject()
        self.GenImport()
        self.GenComponent()
        self.GenComposite()
        self.GenResource()
    #Project
    def GenerateProject(self):
        #require name, id, language, description
        item = self.ctx.Project
        project = xmllib.SubElement(self.root, "Project", {"Id":item["Id"],
                                                      "Name":item["Name"],
                                                      "Language":item["Language"] })
        xmllib.SubElement(project, "Description").text = item["Description"]
    #Import Global namespace
    def GenImport(self):
        self.GenImportType()
        self.GenImportSimApp()        
    def GenImportSimApp(self):
        #Import Default SimApp Types
        ip = xmllib.SubElement(self.root, "Import", {"Id":"RTL" ,
                                                     "Name":"RTL" ,
                                                     "Location":"RTL" })
        tp = xmllib.SubElement(ip, "Type", {"Id":"RTL.Bool",
                                            "Name":"Bool",
                                            "Uuid":"214162B3-D5FA-4b94-BF3A-CD0C95EC85AF",
                                            "xsi:type":"Types:PrimitiveType" })
        #xmllib.SubElement(tp, "Description").text = "表示boolean类型，true或者false".decode("utf-8")
    #Import Structure
    def GenImportType(self):
        #Import Project Defined Structure Types
        item = self.ctx.Import
        ip = xmllib.SubElement(self.root, "Import", {"Id":item["Id"],
                                                     "Name":item["Name"],
                                                     "Location":item["Location"] })
                               
        pass
    #Component
    def GenComponent(self):
        #require type, name, namespace, lvc_feature, ChineseName, EnglishName, creator, department, ddevelopdate, version
        comitem = self.ctx.Component
        com = xmllib.SubElement(self.root, "Component", {"type":comitem["Type"],
                                                            "category":"CompositeComponent",
                                                            "GUID": GenerateGUIDByName(comitem["Type"], comitem["LVC_Feature"]),
                                                            "LVC_Feature":comitem["LVC_Feature"]})
        #Inherit
        xmllib.SubElement(com, "Inherit")
        #Description
        description = xmllib.SubElement(com, "Description")
        ditem = comitem["Description"]
        if ditem == "":
            ditem = BaseContext()
        xmllib.SubElement(description, "ChineseName").text = ditem["ChineseName"]
        xmllib.SubElement(description, "EnglishName").text =ditem["EnglishName"]
        xmllib.SubElement(description, "Creator").text =ditem["Creator"]
        xmllib.SubElement(description, "Department").text =ditem["Department"]
        xmllib.SubElement(description, "DdevelopDate").text =ditem["DdevelopDate"]
        xmllib.SubElement(description, "Version").text =ditem["Version"]
        #Properties
        pps = xmllib.SubElement(com, "Properties")
        if comitem["Properties"] != "":
            for item in comitem["Properties"]:
                pp = xmllib.SubElement(pps, "Property", {"Name":item["Name"]})
                xmllib.SubElement(pp, "Type", {"Href":item["Href"],
                                               "Namespace":item["Namespace"],
                                               "HrefUuid":GenerateUUIDByName(item["Href"], item["Namespace"]) })
                if item["xsitype"] != "Types:StructureValue":
                    xmllib.SubElement(pp, "Default", {"xsi:type":item["xsitype"],
                                                                "Value":item["Value"] })
                else:
                    default = xmllib.SubElement(pp, "Default", {"xsi:type":item["xsitype"] })
                    for k,t,v in item["Value"]:
                        xmllib.SubElement(default, "FieldValue", {"Field":k,
                                                                  "xsi:type": t,
                                                                  "Value":v} )
        #Inputs
        its = xmllib.SubElement(com, "Inputs")
        if comitem["Inputs"] != "":
            for item in comitem["Inputs"]:
                it = xmllib.SubElement(its, "Input", {"Name":item["Name"] })
                xmllib.SubElement(it, "Type", {"Href":item["Href"],
                                                  "Namespace": item["Namespace"],
                                                  "HrefUuid":GenerateUUIDByName(item["Href"], item["Namespace"]) })
        #Outputs
        ots = xmllib.SubElement(com, "Outputs")
        if comitem["Outputs"] != "":
            for item in comitem["Outputs"]:
                ot = xmllib.SubElement(ots, "Output", {"Name": item["Name"] })
                xmllib.SubElement(ot, "Type", {"Href":item["Href"],
                                                  "Namespace": item["Namespace"],
                                                  "HrefUuid":GenerateUUIDByName(item["Href"], item["Namespace"]) })
        #ReceiveEvents
        res = xmllib.SubElement(com, "ReceiveEvents")
        if comitem["ReceiveEvents"] != "":
            for item in comitem["ReceiveEvents"]:
                pass
        #SendEvents
        ses = xmllib.SubElement(com, "SendEvents")
        if comitem["SendEvents"] != "":
            for item in comitem["SendEvents"]:
                pass
        # End of Component
    #Project:Composite
    def GenComposite(self):
        com = xmllib.SubElement(self.root, "Composite")
        #SubComponents
        scs = xmllib.SubElement(com, "SubComponents")
        #InterfaceConnections
        ics = xmllib.SubElement(com, "InterfaceConnections")
        #EventConnections
        ecs = xmllib.SubElement(com, "EventConnections")
        #PropertyMaps
        pms = xmllib.SubElement(com, "PropertyMaps")
        #InputsMap
        im = xmllib.SubElement(com, "InputsMap")
        #OutputsMap
        om = xmllib.SubElement(com, "OutputsMap")
        #End if Composite
    #Project:Resource
    def GenResource(self):
        res = xmllib.SubElement(self.root, "Resource")
    def toXML(self):
        return xmllib.tostring(self.root)
    def write(self,filename):
        #tree = xmllib.ElementTree(self.root)
        #tree.write(filename, "utf-8", xml_declaration=True)
        #tree = xmllib.ElementTree(xe)
        doc = minidom.parseString( xmllib.tostring(self.root) )
        x = doc.toprettyxml(encoding="utf-8")
        f = open(filename, "w")
        f.write(x)
        f.close()

def GetExcelContent(name):
    #return {sheetindex: (sheetname, sheet UsedRange value) dict
    ctx = {}
    book = xlrd.open_workbook(name)
    if book == None:
        raise "Open Excel(%s) failed!" % name
    for i in range(book.nsheets):
        s = book.sheet_by_index(i)
        sname = s.name
        svalue = list()
        for r in range(s.nrows):
            svalue.append( s.row_values(r) )
        ctx[i] = (sname, svalue)
    return ctx
        
#Read Excel file content
def GetExcelContent2(name, oApp=None):
    #return [sheetname --> sheet UsedRange value] dict
    import win32com.client
    ctx={}
    oxl = None
    #Create Excel OLE object
    if oApp == None:
        oxl = win32com.client.Dispatch("Excel.Application")
    else:
        oxl = oApp

    #Open Excel file
    rt = oxl.Workbooks.Open(name)
    if rt == False:
        raise "Open Excel(%s) failed!" %name
    cnt = oxl.ActiveWorkbook.Sheets.Count
    for i in range(cnt):
        sname = oxl.ActiveWorkbook.Sheets[i].Name
        svalue = oxl.ActiveWorkbook.Sheets[i].UsedRange.Value
        ctx[sname]=svalue
    #Close Excel file
    oxl.Workbooks.Close()
    if oApp == None:
        oxl = None

    return ctx

def GenerateStruct(ns, root, etype, edesc, edict):
    iid = "%s.%s" %(ns, etype)
    node = xmllib.SubElement(root, "Type", {"Id": iid,"Name":etype,
                                     "Uuid": GenerateUUIDByName(iid),
                                            "Description":edesc,
                                     "xsi:type":"Types:Structure"} )
    for item in edict:
        ename, dtype, cname, evdesc = item
        iid = "%s.%s.%s" %(ns, etype, ename)
        field = xmllib.SubElement(node, "Field", {"Id":iid,"Name":ename})
        xmllib.SubElement(field, "Type", {"Namespace":"RTL",
                                          "Href":dtype,
                                          "HrefUuid":GenerateUUIDByName(dtype),
                                            "Description":evdesc})
        #print key

#Create XML Structure node
def GenerateStructType(ctx, ns, root=None):
    node = root.find("Namespace")
    EType = ""
    EDesc = ""
    EDict = []
    #列定义：复合数据类型 复合数据描述	属性项英文名称	数据类型	属性项中文名称	粒度
    for i in range(1, len(ctx) ):
        extra = ""
        if len(ctx[i]) < 6:
            break
        elif len(ctx[i]) > 6:
            extra = ctx[i][6]
        etype, edesc, ename, dtype, cname, evdesc = ctx[i][:6]
        if extra != "":
            evdesc = evdesc + "(" + extra + ")"
            
        if etype != "":
            #New enum, before do save
            if EType != "" :
                GenerateStruct(ns, node, EType, EDesc, EDict)
                #break
            EType = etype
            EDesc = edesc
            EDict=[]
            EDict.append( (ename, dtype, cname, evdesc) )
        else:
            EDict.append( (ename, dtype, cname, evdesc) )
    if len(EDict) > 0:#Last one
        GenerateStruct(ns, node, EType, EDesc, EDict)
    return root


def GenerateCompDataType(name, ctx):
    pass
def GenerateEnum(ns, nsnode, etype, edesc, edict):
    iid = "%s.%s" %(ns, etype)
    node = xmllib.SubElement(nsnode, "Type", {"Id": iid,"Name":etype,
                                     "Uuid": GenerateUUIDByName(iid),
                                     "xsi:type":"Types:Enumeration",
                                     "Description":edesc} )
    for item in edict:
        ename, evalue, evdesc = item
        iid = "%s.%s.%s" %(ns, etype, ename)
        xmllib.SubElement(node, "Literal", {"Id":iid,"Name":ename,
                                            "Value":str(int( evalue ) ),
                                            "Description":evdesc})


def GetNsKeyBySheetName(name):
    for k in nslist:
        if name.find(nslist[k][0]) >= 0:
            return k
#Create XML Enumeration node
def GenerateEnumType(name, ctx):
    nskey = GetNsKeyBySheetName(name)
    if nskey == None:
        print "NOT found Sheet name", name.decode('utf-8').encode(dcs)
        return
    nsvalue = nslist[nskey]
    if nsvalue == None:
        raise ValueError("Sheet name error")
    ns = nsvalue[1]
    root = nsvalue[2]
    if root == None:
        root = xmllib.Element("Catalogue:Catalogue", {"Id":"%sDataType" % ns,
                                                      "Name":"%sDataType" % ns,
                                                      "xmlns:Types":"http://www.appsoft.com.cn/Core/Types",
                                                      "xmlns:xlink":"http://www.w3.org/1999/xlink",
                                                      "xsi:schemaLocation":"http://www.appsoft.com.cn/Core/Catalogue Core/Catalogue.xsd",
                                                      "xmlns:Catalogue":"http://www.appsoft.com.cn/Core/Catalogue",
                                                      "xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance"})
    node = root.find("Namespace")
    if node == None:
        node = xmllib.SubElement(root, "Namespace", {"Id":ns, "Name":ns})
        xmllib.SubElement(node, "Description").text = "It is the data type definition of namespace named %s ." % ns

    EType = ""
    EDesc = ""
    EDict = []
    #列定义：数据类型 数据描述 枚举项 值 值定义
    for i in range(1, len(ctx)): #枚举行
        extra = ""
        if len(ctx[i]) <5:
            break
        elif len(ctx[i]) >5:
            extra = ctx[i][5]
        etype, edesc, ename, evalue, evdesc = ctx[i][:5]
        if extra != "":
            evdesc = evdesc + "(" + str(extra) + ")"
        if etype != "":
            #New enum, before do save
            if EType != "" :
                GenerateEnum(ns, node, EType, EDesc, EDict)
                #break
            EType = etype
            EDesc = edesc
            EDict=[]
            EDict.append( (ename, evalue, evdesc) )
        else:
            EDict.append( (ename, evalue, evdesc) )
    if len(EDict) > 0:#Last one
        GenerateEnum(ns, node, EType, EDesc, EDict)
    nsvalue[2] = root
def FindFileBySurfix(flist, folder, surfix):
    files = os.listdir(folder)
    for fi in files:
        #decode filename from gbk to unicode codeset
        if type(fi) == str:
            fi = fi.decode(dcs)
        name = folder + os.path.sep + fi
        if os.path.isdir(name):
            #recursion call
            FindFileBySurfix(flist, name, surfix)
        elif os.path.isfile(name):
            for sfix in surfix:
                if name[-len(sfix):] == sfix :
                    flist.append(name)
                    break
def GetFileList(folder, surfixs=".xls,.xlsx"):
    """ 遍历文件夹查找所有满足后缀的文件 """
    surfix = surfixs.split(",")
    if type(folder) == str:
        folder = folder.decode('utf-8')
    p = os.path.abspath(folder)
    flist = []
    if os.path.isdir(p):
        FindFileBySurfix(flist, p, surfix)
    else:
        raise "folder param(%s) is not a real folder" % str(folder)
    utf8list=[]
    for it in flist:
        utf8list.append(it.encode('utf-8'))
    return utf8list

#Check Excel file model type
def CheckExcelFileModel(apath):
    ret=[]
    folder, name = os.path.split(apath);
    #check folder type
    h ,t = os.path.split(folder)
    #Namespace
    ns_key = t[:2]
    if ns_key == default_ns_key:
        #Global namespace
        ns=nslist[ns_key]
        ret.append(ns[1])
        #File type
        lv = pglobal.findall(name)
        if len(lv) == 1:
            ret.append( lv[0] )
            ret.append( lv[0] )
            ret.append( lv[0] )
    elif nslist.has_key(ns_key):
        #Other namespace
        ns=nslist[ns_key]
        ret.append(ns[1])
        #File type
        lv = pother.findall(name)
        if len(lv) ==1 and len(lv[0]) == 3:
            ret.append(lv[0][0])
            ret.append(lv[0][1])
            ret.append(lv[0][2])
    else:
        #default namespace
        ns = nslist[default_ns_key]
        ret.append(ns[1])
        #File type
        lv = pother.findall(name)
        if len(lv) ==1 and len(lv[0]) == 3:
            ret.append(lv[0][0])
            ret.append(lv[0][1])
            ret.append(lv[0][2])
    if len(ret) == 4:
        return ret

#Generate Data structure XML (enum, struct, array)
def GenerateDataStruct(args):
    #(namespace, filelist) --> default Utf-8 encoding
    ns, flist = args
    flist = flist.decode('utf-8').split(',')
    #Find global etree root node ->nsvalue[2]
    nsvalue=[]
    for k in nslist:
        if nslist[k][1] == ns:
            nsvalue = nslist[k]
            #Clear existing data
            #nsvalue[2] = None
            break

    #Loop each Excel file in flist
    for xls in flist:
        if xls == '':
            continue
        #print "xls ctx generated!", xls
        #Ctx: {index->(name, value)}
        #print type(xls), xls
        ctx = GetExcelContent(xls)
        xlfile = os.path.split(xls)[1]


        #Public struct Excel style (检查规则：文件以0开头)
        if xlfile[0] == '0' :
            if xlfile.find('EnumDataType') >= 0:
                #Excel struct: (枚举数据类型名称 数据类型描述 枚举项 值 值定义)
                #Loop each sheet by sheet index
                for isheet in ctx:
                    sheet_name, sheet_ctx = ctx[isheet]
                    #print "Call GenerateEnumType"
                    generator.GeneratePublicEnumDataType(sheet_name, sheet_ctx)
                    #GenerateEnumType(sheet_name.encode('utf-8'), sheet_ctx)
            elif xlfile.find('CompDataType') >= 0:
                #Excel struct: (复合结构数据类型名称 ns 数据类型描述 数据项名称 ns1
                #数据项中文名称 数据项数据类型 粒度 单位 默认值 最小值 最大值 数据项描述)
                #Loop each sheet by sheet index
                for isheet in ctx:
                    sheet_name, sheet_ctx = ctx[isheet]
                    #print "Call GenerateCompDataType"
                    generator.GeneratePublicCompDataType(sheet_name, sheet_ctx)
                    #GenerateCompDataType(sheet_name.encode('utf-8'), sheet_ctx)
            elif xlfile.find('ArrayDataType') >= 0:
                for isheet in ctx:
                    sheet_name, sheet_ctx = ctx[isheet]
                    print "Call GenerateArrayType", sheet_name.encode('gbk')
                    generator.GeneratePublicArrayDataType(sheet_name, sheet_ctx)
                    #GenerateEnumType(sheet_name.encode('utf-8'), sheet_ctx)
        else: #模型的数据结构定义文件 (输入输出消息，发送接收事件)
            if len(ctx) > 2:
                for i in range(1, 3):
                    sh_name, sh_ctx = ctx[i]
                    print "Call GenerateCustomCompDataType"
                    generator.GeneratorCustomCompDataType(xlfile, sh_name, sh_ctx)
def SaveDataStruct():
    print "Call SaveDataStruct"
    files = generator.Save()
    #print files
    Init();
#    for k in nslist:
#        nsvalue = nslist[k]
#        root = nsvalue[2]
#        if root == None:
#            continue
#        name = "%s.xml" % nsvalue[1]
#        name = os.path.abspath(name)
#        print "save ", name
#        doc = minidom.parseString( xmllib.tostring(root) )
#        x = doc.toprettyxml(encoding="utf-8")
#        f = open(name, "w")
#        f.write(x)
#        f.close()
#        files.append(name)
    return files

def test(num):
    print "calling test ", num
##if __name__ == "__main__":
    ctx = BaseContext()
    #Project
    ctx.Project=BaseContext()
    ctx.Project.name = "test project name"
    ctx.project.language = "C++"
    ctx.project.description="这事一个测试程序".decode("utf-8")
    ctx.Project.Id="test project"
    #Component
    ctx.Component = BaseContext()
    ctx.Component.LVC_Feature="Constructive"
    ctx.Component.Type="TestProject"
    #Description
    ctx.Component.Description = BaseContext()
    dp = ctx.Component.Description
    dp.ChineseName=u"测试程序"
    dp.EnglishName="TestProject"
    dp.creator = "Hehao"
    dp.department=u"开发部"
    dp.ddevelopdate=time.strftime("%Y-%m-%d %H:%M:%S")
    dp.version = "Version1.0"
    #Properties
    ctx.Component.Properties = list()
    pps = ctx.Component.Properties
    pp = BaseContext()
    pp.Name = "Radius"
    pp.Href = "Float64"
    pp.Namespace = "RTL"
    pp.xsitype = "Types:Float64Value"
    pp.value = "0.0"
    pps.append(pp)
    #Import
    ctx.Import = BaseContext()
    ctx.Import.id = ctx.Import.name = ctx.Import.location = "Dist3NS"

    #print ctx.Component, ctx.Component.has_key("properties")

    gen = DSCFileGenerator("test", ctx)
    gen.Generate()
    print
    print os.path.split(os.path.abspath(__file__))[0] + os.path.sep + "testdsc.xml"
    gen.write("testdsc.xml")
    return ("testdsc.xml","123")
    #print gen.toXML()
##if __name__ == "__main__":
def parseFile(name):
##    flist = GetFileList("I:\\work\\autotools")
##    print "count Excel ", len(flist)
##    for f in flist:
##        print f.decode(dcs)
    name = name.decode('utf-8')
    ctx = GetExcelContent(name)
    print "\n\nExcel sheets", len(ctx)
    for i in ctx:
        print type(i)
        print i.encode(dcs)
        print "col=", len( ctx[i] )
        if len(ctx[i] ) > 0:
            print "row=", len(ctx[i][0]), " \ncolumn names:"
            for j in ctx[i][0]:
                print j.encode(dcs)
##    #print GenerateUUIDByName("hello")
    enm = "0A_EnumDataType.xls";
    xe = None
    print name.encode('utf-8')[-len(enm):], name.encode('utf-8')[-len(enm):] == enm
    if name.encode('utf-8')[-len(enm):] == enm:
        for i in ctx:
            #print "generate enum type sheet:", i.encode(dcs)
            xe = GenerateEnumType(ctx[i], "Dist3", xe)
            print xe
    #GenerateStructType(ctx["复合数据类型表".decode("utf-8")], "Dist3", xe)
    tree = xmllib.ElementTree(xe)
    doc = minidom.parseString( xmllib.tostring(xe) )
    x = doc.toprettyxml(encoding="utf-8")
    f = open("output.xml", "w")
    f.write(x)
    f.close()
    #tree.write("output.xml", "utf-8", xml_declaration=True)
    return os.path.abspath("output.xml")
##    tree.write(os.path.split(os.path.abspath(__file__))[0] + os.path.sep + "output.xml", "utf-8", xml_declaration=True)
##    #print xmllib.tostring(xe, "utf-8")

if __name__ == "__main__":
    print default_ns_name
    #import projectmodel as pm
    #dt = pm.DataType()
    #dt.ImportXML(r"I:\dist3\20151229\model\code\modelingtools\RTL_Types.xml")
    #dt.ImportXML(r"I:\work\build-qautotools-Desktop_Qt_5_3_MinGW_w64_32bit_MSYS2-Debug\NTSim_Comm.xml")
    #print GetFileList("i:\\dist3\\20151229\\model")
    ctx = GetExcelContent(r"I:\dist3\20151229\model\接口设计\excel\0_枚举和复合结构数据类型\0B_CompDataType.xls".decode('utf-8'))
    print len(ctx)
    sheet_name, sheet_ctx = ctx[0]
    import datatypefile_generator as gen
    g = gen.DataTypeFileGenerator("Dist3Demo", nslist=nslist)
    g.GeneratePublicCompDataType(sheet_name, sheet_ctx)
    print g.root
    g.Save()

    #doc = minidom.parseString( xmllib.tostring(g.root, 'utf-8') )
    #x = doc.toprettyxml(encoding="utf-8")
    #f = open("output.xml", "w")
    #f.write(x)
    #f.write(xmllib.tostring(g.root, 'utf-8'))
    #f.close()
